﻿/**
@mainpage Проект по созданию упрощённой системы защиты информации от несанкционированного доступа.
 * 
@author Бадосов Николай Геннадьевич     - руководитель проекта    - badosov@ya.ru
@author Василенко Анатолий Эдуардович   - разработчик-архитектор  - anatoly.vasilenko.2@gmail.com
@author Глотов Евгений Сергеевич        - разработчик-дизайнер    - glot.unltd@gmail.com
@author Ожерельев Илья Сергеевич        - разработчик             - ilya365365@gmail.com
@author Cендерович Никита Леонидович    - разработчик             - niksettler@gmail.com
@author Слюсарь Даниил Романович        - разработчик             - danya.brain@gmail.com
@author Лазовский Руслан Александрович  - разработчик             - gospbuff@gmail.com
@author Кириллов Валентин Владимирович  - разработчик             - kvvpochta94@gmail.com
@author Петров Константин Игоревич      - разработчик             - petrov.k.i.02@gmail.com
@author Земцов Евгений Евгеньевич       - разработчик             - zemtsov.e.e@gmail.com
@author Исхаков Эльдар Ансарович        - разработчик             - eldar_111@mail.ru (ndsipu314@gmail.com)
 * 
@date осень 2014 год
 * 
 * Данный продукт является opensource проектом, и разрабатывался при помощи системы контроля версий git.<br>
 * Исходный код можно скачать по ссылке: https://code.google.com/p/defensiveshield/
 * 
 * Данный проект является работой в рамках задания на военной кафедре студентов взвода 2331.
 * Данный программный продукт позволяет оперировать с секретными файлами, защищёнными от внешнего просмотра, а так же разграничивать доступ к файлам в соответствии с дискреционной и мандатной моделью.
 * Реализуемая дискреционная модель является расширенной, т.к. в дополнение к групповому распределению прав доступа, администратор системы имеет право указывать права доступа на каждого отдельного пользователя системой.
 * 
 * Шифрование в системе реализуется с использованием внешней подключаемой библиотеки.
 * 
 * Программный продукт является переносимым ("portable")
 * 
*/

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace DefensiveShield
{
    
///////// Data Structures

    //=================================================================================================================================
    //==================================================================================================== SECURITY LABEL =============
    //=================================================================================================================================
    /**
        @enum Secrecy
         * Перечислимый тип для указания уровня доступа в мандатном распределении прав доступа
         * Секретность может отсутствовать, либо может принимать один из следующих 3-х уровней доступа:
         * <ol>
         *      <li> Конфиденциально
         *      <li> Секретно
         *      <li> Совершенно секретно
         * </ol>
    */
    public enum Secrecy
    {
        NonSecret = 0,
        StaffOnly = 1,
        Confidential = 2,
        Secret = 3,
        TopSecret = 4
    }

    //=================================================================================================================================
    //==================================================================================================== RIGHTS =====================
    //=================================================================================================================================
    /**
        @enum Rights
         * Перечислимый тип для указания дискреционных прав доступа к файлу.
         * Доступ к файлу может быть одним из следующих:
         * <ol>
         *      <li> Нет доступа
         *      <li> Доступ на чтение
         *      <li> Доступ на чтение и запись (или исполнение если это исполнимый файл)
         * </ol>
    */
    public enum Rights
    {
        Noright = 0,
        Read = 1,
        ReadWrite = 2
    }

    //=================================================================================================================================
    //==================================================================================================== INTEGRITY ==================
    //=================================================================================================================================
    /**
        @enum Integrity
         * Перечислимый тип для указания результата проверки целостности для файла
         * Результат проверки может быть одним из следующих:
         * <ol>
         *      <li> Целостность файла сохранена
         *      <li> Целостность файла нарушена
         *      <li> Целостность файла не проверена по корректным причинам
         *      <li> Цулостность файла не проверена из-за непредвиденной ошибки
         * </ol>
    */
    public enum Integrity
    {
        Valid = 0,
        Corrupted = 1,
        Unchecked = 2,
        ErrorAppeared = 3
    }

    //=================================================================================================================================
    //==================================================================================================== ERROR CODES ================
    //=================================================================================================================================
    /**
        @enum ErrorCodes
         * Перечислимый тип используемый внутри программы для указания кода ошибки, возникшей в той или иной функции.
    */
    public enum ErrorCodes
    {
        NoError = 0, // It is important that this value is 0
        UnknownError,
        OpenAttemptOfUnregisteredFile,
        AttemptToRegisterRegisteredFile,
        AttemptToRegisterNonDirectoryAndNonExecutable,
        AttemptToRegisterUnexistedFile,
        WrongPassword,
        UnknownErrorInCheckUserPassword,
        ErrorInCheckingUserPassword,
        NotAdminLogin,
        ErrorInDeletingOsSession,
        MandatoryAccessDenied,
        AttemptToDeleteAdministrator,
        NotEnoughPermissionsToDeleteFile,
        UnknownLoggingError,
        ErrorDeletingLogFile,
        FileNotWritable,
        DeleteAttemptOfUnregisteredFile,
        DeleteAttemptOfExecutable,
        NotEnoughPermissionsToCreateDirectory,
        AttemptToRunNonExecutable,
        NotEnoughPermissionsToExecuteFile,
        ErrorStartingSeveralApplicationInstances,
        IntegrityErrorFileDoesNotExist,
        IntegrityErrorFileAlreadyIsChecking,
        ErrorInTakingHashInIntegrityAdder,
        NotEnoughPermissionsToDeleteFileFromIntegrityCheck,
        ErrorWhileCheckingFilesIntegrity,
        IntegrityCorrupt,
        CryptoDllEncryptionDecryptionCorrupt,
        CryptoDllAbsent,
        CryptoDllError,
        WrongGlobalKeyPassword
    }

    //=================================================================================================================================
    //==================================================================================================== FILE TYPE ==================
    //=================================================================================================================================
    /**
        @enum FileType
         * Перечислимый тип для указания типа объекта файловой системы, к которому может быть реализован доступ.
         * Объект может быть одним из следующих:
         * <ol>
         *      <li> Директория
         *      <li> Текстовый файл
         *      <li> Исполняемый файл (определяется по наличию у файлу необходимого постфикса ".exe")
         * </ol>
    */
    public enum FileType
    {
        Directory = 0, // Disc is directory
        TextFile,
        Executable,
        Other
    }

    //=================================================================================================================================
    //==================================================================================================== USERS PASSPORT =============
    //=================================================================================================================================
    /**
        @class UserPassport
        @brief Системные параметры пользователя
         * Используется для хранения данных о пользователе: его логин, пароль, права доступа
         * 
         * Когда пользователь создаёт новую директорию или секретный файл, то права доступа на созданный им объект копируются в параметры самого объекта, и если в последствии политики доступа пользователей к создаваемым объектам этим пользователем будут изменены, то файлу, которые уже созданы останутся с неизменными правами.
         * 
         * Файлы и папки в системе идентифицируются по их полному пути, и для того, чтобы существовала некоторая единая система, все разработчики обязаны использовать для хождения по файловой системе стандартный статический класс Directory, а для работы с файлами использовать FileSystemInfo, FileInfo, DirectoryInfo
    */
    public class UserPassport
    {
        /// Логин пользователя
        // Hashable variable
        public string UserName;
        /// Хеш от пароля пользователя
        public string PasswdHash;
        /// Название группы пользователя
        // must be == "" if user is not participating in any group
        public string GroupName;
        /// Уровень допуска пользователя в рамках мандатной модели разграничения доступа
        public Secrecy SecrecyNum;
        /// Права для доступа к созданной пользователем директории других пользователей, состоящих в его группе
        public Rights GroupRightsDirectory;
        /// Права для доступа к созданной пользователем директории других пользователей, которые не состоят в его группе
        public Rights OthersRightsDirectory;
        /// Права для доступа к созданному пользователем секретному файлу других пользователей, состоящих в его группе
        public Rights GroupRightsFile;
        /// Права для доступа к созданному пользователем секретному файлу других пользователей, которые не состоят в его группе
        public Rights OthersRightsFile;
        /// Путь к домашней директории пользователя, которая автоматически создаётся при создании пользователя
        public string HomeDirectory;
    }

    //=================================================================================================================================
    //==================================================================================================== FILE PASSPORT ==============
    //=================================================================================================================================
    /**
        @class FilePassport
        @brief Системные параметры файла
         * Используется для хранения данных зарегистрированных объектов из файловой системы.
         * 
         * Любой текстовый файл, который был зарегистрирован в нашей системе является либо секретным и шифруется на некотором ключе, либо исполняемым
    */
    public class FilePassport
    {
        /// Полный путь к зарегистрированному объекту в файловой системе
        // Hashable variable
        public string FileName;
        /// Тип объекта
        public FileType FileTypeNum;
        /// Уровень секретности файла в рамках мандатной модели разграничения доступа
        public Secrecy SecrecyNum;
        /// Создатель файла
        public string OwnerName;
        /// Название группы пользователей, к которой возможно применение групповых политик дискреционного разграничения доступа
        public string GroupName;
        /// Права доступа членов группы, в рамках дискреционного разграничения доступа
        public Rights GroupRights;
        /// Права доступа пользователей, не входящих в состав группы, в рамках дискреционного разграничения доступа
        public Rights OtherRights;

        /// Ключ, на котором шифруется секретный файл (если объектом файловой системы является не секретный файл, то поле должно быть == null)
        public string Key;

        /// Словарь, в котором указываются исключительные права для каждого отдельного пользователя на данный объект
        /// Предназначено для ввода исключений из групповых политик дискреционного разграничения доступа
        public Dictionary<string, Rights> ExclusiveUserAccessRights;

        /// Флаг, объявляющий, что файл уже открыт в нашей файловой системе, этот параметр был создан на будущее, для возможности создания параллельной работы пользователей в системе, но не параллельной работы польхователей над одним файлом
        /// Не используется
        public bool FileOpened;

        public FilePassport()
        {
            ExclusiveUserAccessRights = new Dictionary<string, Rights>();
            FileOpened = false;
        }
    }

    //=================================================================================================================================
    //==================================================================================================== OS SESSION =================
    //=================================================================================================================================
    /**
        @brief Класс, содержащий параметры пользовательской сессии
         * Этот класс используется для хранения текущих настроек пользовательской сесии.
         * 
         * В данной реализации он является полностью статическим, т.к. количество сессий в данной реализации всегда одно, но в случае добавления возможности вести многопользовательские сессии, он должен будет стать не статическим.
    */
    public partial class OsSession
    {
        /// Это число используется для подсчёта количества неудачных попыток ввода пароля подряд, чтобы при достижении некоторого количества можно было осуществить соответствующие действия.
        public uint FailedAuthorization;

        /// Имя пользователя, который сейчас вошёл в систему
        public string UserName;

        /// Уровень допуска пользователя, в рамках текущей сессии этого пользователя.<br>
        /// Используется для отслеживания уровней секретности файлов, которые пользователь открывает.
        public Secrecy SessionSecrecy;

        private const uint AvailableAuthorizationAttemptsNum = 3;

        //---------------------------------------------------------------------------------------------------------------------------------
        //---------------------------------------------------------------------------------------------------- OS SESSION CONSTRUCTOR -----
        //---------------------------------------------------------------------------------------------------------------------------------
        /**
            @brief Конструктор, инициализирующий сессию пользователя
        */
        public OsSession()
        {
            FailedAuthorization = 0;
            UserName = "";
            SessionSecrecy = Secrecy.NonSecret;
        }
    }

    //=================================================================================================================================
    //==================================================================================================== OS =========================
    //=================================================================================================================================
    /**
        @brief Основной класс системы.
         * 
         * Здесь хранятся данные о всех пользователях и зарегистрированных объектах файловой системы.
         * Здесь так же реализованны все основные функции для управления ими.
         * 
         * Класс является статическим, т.к. отображает собой отдельный экземпляр комплексной системы разграничения прав.
    */
    public static partial class OS
    {
        /// Словарь всех пользователей, которые зарегистрированны в системе.<br>
        /// Имя каждого пользователя обязано быть униклальным.
        public static Dictionary<string, UserPassport> Users;

        /// Словарь всех зарегистрированных объектов файловой системы.<br>
        /// В качестве идентификатора используется полный путь к файлу/папке.
        public static Dictionary<string, FilePassport> Files;

        /// Список сессий, которые открыты в рамках операционной системы
        /// Количество сессий и принадлежность их к одному и тому же или к разным пользователям может быть любая, поэтому используется список
        public static List<OsSession> Sessions;

        /// Логин администратора системы (администратор системы - лишь один)
        public static string AdministratorName;

        /// Пароль от системы вводится администратором системы, должен совпадать с паролём администратора
        public static string SystemPassword;

        /// Глобальный ключ шифрования (его значение прописано в программе)
        public static string GlobalKey;

        /// Глобальная строка длинной 512 бит, являющаяся инициализационным вектором для функции хеширования
        public static string IV;

        /// Класс содержащий текущее состояние файла, включённого в проверку целостности.
        public class IntegrityState
        {
            public string HashValue;
            public Integrity IntegrityValue;
        }

        /// Словарь, используемый для проверки целостности системы.<br>
        /// В этом словаре находится список файлов, которые были добавлены, как файлы, для которых должна существовать проверка целостности и хеши их содержимого
        public static Dictionary<string, IntegrityState> FileIntegrity;
        /// Дата и время последней проверки целостности файлов
        public static DateTime DateLastIntegritySnapshot;

        /// Полный путь к файлу, где лежат следующие параметры системы: IV системы и зашифрованнй GlobalKey системы на пароле администратора.
        private static string _baseSystemConfigurationFileName;
        /// Полный путь к файлу, где лежат все настройки системы
        private static string _configurationFileName;
        /// Полный путь к файлу, в который ведётся логгирование событий
        private static string _logFullFileName;

        /// Mutex используемый для того, чтобы определить является ли запущенное приложение единственной копией на этом компьютере
        private static Mutex _mutexForSingleApplicationInstance;
    }
}
